//
//  DFUView.swift
//  TLCLockDemo
//
//  Created by run on 2024/7/16.
//

import Combine
import CryptoSwift
import SwiftUI
import TLCLock

class DFUModel: SheetModel {
    var cancellable: AnyCancellable?
    let device: LockDevice

    init(device: LockDevice) {
        self.device = device
    }

    deinit {
        cancellable?.cancel()
        debugPrint("DFUModel deinit")
    }
}

struct DFUView: View {

    let model: DFUModel

    @State var message: String = "提示"
    @State var romUrl: String = Server.romUrl
    @State var romMd5: String = Server.romMd5Str

    var body: some View {
        VStack(alignment: .center, spacing: 20) {
            YxrInputView("Rom URL", text: $romUrl)
            YxrInputView("Rom Md5", text: $romMd5)
            
            Text(message)
                .font(.body)
                .foregroundColor(.blue)
                .padding()
                .frame(minWidth: 40, maxWidth: .infinity, minHeight: 34, maxHeight: 50, alignment: .leading)
                .cornerRadius(10)
            
            YxrConfirmView(title: "点击开始更新") {
                if model.cancellable != nil {
                    showToast("正在更新，请勿重复点击")
                    return
                }
                onTapUpgrade()
            }
            
            YxrConfirmView(title: "停止更新") {
                self.stopUpgrade()
            }
        }
        .yxrNavigationTitle("锁升级")
        .onDisappear(perform: {
            self.stopUpgrade()
        })
    }

    func stopUpgrade() {
        model.cancellable?.cancel()
        model.cancellable = nil
        Log.info("停止更新rom")
    }

    func onTapUpgrade() {
        if romUrl.isEmpty {
            message = "请输入romUrl"
            return
        }

        guard let lockKey = Server.getSecret(model.device.macAddress) else {
            message = "无lockKey"
            return
        }
        
        // 防止屏幕休眠
        UIApplication.shared.isIdleTimerDisabled = true

        Task {
            do {
                guard let data = try await Server.getRomData(romUrl) else {
                    self.message = "没有更新数据"
                    return
                }

                let md5Str = data.md5().toHexString()

                Log.info("当前data的md5: \(md5Str)")
                guard md5Str == romMd5 else {
                    self.message = "数据不正确"
                    return
                }

                model.cancellable = try self.model.device.upgrade(data: data, md5Str: md5Str, lockKey: lockKey, trackId: Server.testTrackId).sink { completion in
                    switch completion {
                    case .finished:
                        self.message = "更新完成"
                    case let .failure(error):
                        self.message = "更新失败: \(error.localizedDescription)"
                    }
                    
                    // 更新完成，解除屏幕不能休眠
                    DispatchQueue.main.async {
                        UIApplication.shared.isIdleTimerDisabled = false
                    }
                } receiveValue: { percent in
                    self.message = "更新进度：\(percent.toPercentString())"
                    Log.info("更新进度：\(percent)")
                }
            } catch {
                self.message = error.localizedDescription
            }
        }
        
    }
}

extension Double {
    static let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .percent
        formatter.maximumFractionDigits = 2
        return formatter
    }()

    func toPercentString() -> String {
        return Double.formatter.string(for: self) ?? String(format: "%.2f%", self * 100) + "%"
    }
}
